package cn.infrabase.core.io.file;

import cn.infrabase.core.io.IoRuntimeException;

import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;

/**
 * @author Weimin Gao
 * @since 1.0.0
 **/
public class PathUtils {

    /**
     * 判断给定的路径是否为目录，如果路径为null，则返回false。
     *
     * @param path          给定的路径。
     * @param isFollowLinks 是否追踪到软链对应的真实地址。
     * @return 真（true）表示是目录。
     */
    public static boolean isDirectory(Path path, boolean isFollowLinks) {
        if (null == path) {
            return false;
        }
        final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
        return Files.isDirectory(path, options);
    }

    /**
     * 判断给定的路径是否为目录，如果路径为null，则返回false，此方法不会追踪到软链对应的真实地址，即软链被当作文件。
     *
     * @param path 给定的路径
     * @return 真（true）表示是目录。
     */
    public static boolean isDirectory(Path path) {
        return isDirectory(path, false);
    }

    /**
     * 判断给定路径对应的文件或目录是否存在。
     *
     * @param path          给定的路径。
     * @param isFollowLinks 是否跟踪软链（快捷方式）。
     * @return 真（true）表示存在。
     */
    public static boolean exists(Path path, boolean isFollowLinks) {
        final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
        return Files.exists(path, options);
    }

    /**
     * 创建给定路径对应的目录及其父目录。
     *
     * @param dir 给定的路径。
     * @return 路径对象。
     */
    public static Path mkDirs(Path dir) {
        if (null != dir && !exists(dir, false)) {
            try {
                Files.createDirectories(dir);
            } catch (Exception e) {
                throw new IoRuntimeException(e,String.format("循环创建给定路径对应的目录发生错误，路径【%s】，错误【%s】", dir, e.getMessage()));
            }
        }
        return dir;
    }

    /**
     * 创建给定路径对应的父目录，如果给定的路径已是根目录则直接返回给定的路径。
     *
     * @param path 给定的路径。
     * @return 路径对象。
     */
    public static Path mkParentDirs(Path path) {
        Path parent = path.getParent();
        if (parent == null) {
            return path;
        }
        return mkDirs(parent);
    }
}
